

#include "multask.h"

TIMER *task_timer ; 
TASK_MANAGEMENT *task_man ;


TASK *task_init (MEMORY_MANAGEMENT *memman ) { 
	int i ;
	TASK  * task ,* idle ;  
	SEGMENT_DESCRIPTOR *gdt = ( SEGMENT_DESCRIPTOR *) ADR_GDT; 
	task_man = (TASK_MANAGEMENT *)memman_alloc_4k(memman,sizeof (TASK_MANAGEMENT)) ;
	for (i = 0 ; i < MAX_TASKSIZE ; i++) { 
		task_man->tasks0[i].flags = 0 ; 
		task_man->tasks0[i].gdtid = (TASK_GDT0 +i)*8 ;
		task_man->tasks0[i].tss.ldtr = (TASK_GDT0 +MAX_TASKSIZE +i)*8 ; //设置ldt段为 MAX +i  这里的MAX为100 ，总的分配给任务调度的gdt约为1000个,所以够用 
		set_segmdesc(gdt +TASK_GDT0 +i, 103,(int) &task_man->tasks0[i].tss, AR_TSS32);
		set_segmdesc(gdt +TASK_GDT0 +MAX_TASKSIZE +i, 15,(int) &task_man->tasks0[i].ldt, AR_LDT);
	}
	for (i = 0 ; i<MAX_TASKLEVELS ;i ++) { 
		task_man->tasklevels[i].running = 0 ;
		task_man->tasklevels[i].now = 0 ;
	}



	//添加bootpack.c的task任务到任务调度中，以便处理鼠标键盘等中断
	task = task_alloc () ;
	task->priority = 2 ;//0.02 秒
	task->flags = TASK_STATUS_ACTIVE ; //活动中
	task->level = 0 ;
	task_add (task);
	task_switchsub () ;//
	//task_man->running =1 ;
	//task_man->tasks[0] = task ; 
	//task_man->now = 0 ;
	load_tr(task->gdtid);
	task_timer = timer_alloc () ;
	timer_settime (task_timer,task->priority);


	//添加闲置任务 ，在无任务的情况下进入闲置任务
	idle = task_alloc () ;
	idle->tss.esp = memman_alloc_4k(memman,64 * 1024) +64 *1024 - 8 ;
	idle->tss.eip = (int) &task_idle; 
	
	idle->tss.es = 1 * 8;
	idle->tss.cs = 2 * 8;
	idle->tss.ss = 1 * 8;
	idle->tss.ds = 1 * 8;
	idle->tss.fs = 1 * 8; 
	idle->tss.gs = 1 * 8;
	task_run (idle ,MAX_TASKLEVELS-1,1); //闲置任务 ，优先级最低，间隔0.01s
	return task ;

}
//绑定task 和cqueue
void task_bindcq(TASK * task ,CQUEUE * cq) { 
	task->cq = cq ; 
	cq->task = task ;
}

TASK* task_alloc (void ) { 
	int i  ;
	TASK * task ; 
	for (i= 0 ; i < MAX_TASKSIZE ; i++) { 
		if (task_man->tasks0[i].flags ==0 ){ 
			task->priority = 2 ; //0.02秒 
			task = &task_man->tasks0[i] ;
			task->flags =TASK_STATUS_USED ; //正在使用
			task->tss.eflags = 0x00000202; /* IF = 1; */
			task->tss.eax = 0; /* 暂时先设定为0 */
			task->tss.ecx = 0;
			task->tss.edx = 0;
			task->tss.ebx = 0;
			task->tss.ebp = 0;
			task->tss.esi = 0;
			task->tss.edi = 0;
			task->tss.es = 0;
			task->tss.ds = 0;
			task->tss.fs = 0;
			task->tss.gs = 0;
		//	task->tss.ldtr = 0;
			task->tss.iomap = 0x40000000;
			task->tss.ss0 = 0 ;

			task->cmd = 0 ;
			return task;

		}
	}
	return 0 ;
}
void task_run (TASK * task ,int level ,int priority ) {
	if (level <0 ) { 
		level = task->level ; 
	}
	if (priority > 0 ) { 
		task->priority = priority ;
	}
	if (task->flags ==TASK_STATUS_ACTIVE && task->level != level ) { 
		task_remove (task);
	}
	if (task->flags !=TASK_STATUS_ACTIVE ){
		task->level = level ; 
		task_add(task);
		
	}
	task_man->lv_change =1 ; 
	return  ;
}

void task_switch (void ) { 
	TASK_LEVEL * tl =&task_man->tasklevels[task_man->now_lv] ;
	TASK * task ,*now_task = tl->tasks[tl->now];

	tl->now ++ ;
	if (tl->now ==tl->running) { 
		tl->now =0 ;
	}

	if (task_man->lv_change !=0 || task_man->tasklevels[task_man->now_lv].running <=0) { 
		task_switchsub () ;
		tl  = &task_man->tasklevels[task_man->now_lv] ;
	}
	task = tl->tasks[tl->now] ;
	timer_settime (task_timer ,task->priority); //设置下一次切换的时间为task的优先级 
	
	if (task != now_task ){
		farjmp (0 ,task->gdtid);
	}

	return  ;
}

void task_switchsub () { 
	int i  ; 
	for (i= 0 ;  i < MAX_TASKLEVELS ; i++) { 
		if (task_man->tasklevels[i].running >0 ) { 
			break  ;
		}
	}
	task_man->now_lv = i ;
	task_man->lv_change = 0 ;
	return ;
}


void task_sleep (TASK * task ) { 
	int i ;  
	TASK * now_task  ;
	if (task->flags ==TASK_STATUS_ACTIVE) { 
		now_task = task_now () ;
		task_remove (task) ;
		if (task == now_task) { //如果是当前正在运行的任务，需要farjmp 
			task_switchsub () ;
			now_task = task_now () ;
			farjmp (0 ,now_task->gdtid) ;
		}

	}
	return ;
}

 TASK * task_now () { 
 	TASK_LEVEL * level = &(task_man->tasklevels[task_man->now_lv]) ;
 	return level->tasks[level->now] ; 
 }

 void task_add (TASK * task) { 
 	TASK_LEVEL  * level = &(task_man->tasklevels[task->level]) ; 
 	 level->tasks[level->running]  = task  ;
 	 level->running ++ ;
 	 task->flags = TASK_STATUS_ACTIVE ;  
 }       



 void task_remove (TASK * task ) {
 	int i ; 
 	TASK_LEVEL * tl = &task_man->tasklevels[task->level] ;
 	if (task->flags ==TASK_STATUS_USED) { 
 		return  ;
 	}
 	for (i = 0 ; i  < tl->running ; i++) { 
		if (tl->tasks[i] ==task ) { 
			break  ;
		}
	}
 	tl->running -- ;
	if (i < tl->now ) { 
		tl->now -- ; /*判断now的位置 ，如果now在i右边，因为要左移1 ，所以减1*/
	}
	for (; i < tl->running ;i++) {  //把i右边的task左移1位
		tl->tasks[i] = tl->tasks[i+1] ;
	}
	task->flags = TASK_STATUS_USED; //替换为只注册状态，但不active
	return ; 	
 }

//闲置任务
void task_idle () { 
	for (;;) { 
		io_hlt () ;
	}
}    

  